package com.itcast.demo.service;

import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.Map;

/**
 * @author sai
 * @version 1.0
 * @date 2021/8/17 15:55
 */
@Slf4j
@Service
public class ElasticsearchService {

    @Autowired
    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    private RestHighLevelClient client;

    /**
     * 根据索引名称删除索引
     * @param indexName 索引名称
     * @return 操作完成返回true,操作出现异常返回false
     */
    public Boolean deleteIndex(String indexName) {
        // 1 构建请求
        DeleteIndexRequest request = new DeleteIndexRequest(indexName);

        // 2 发出请求
        try {
            client.indices().delete(request, RequestOptions.DEFAULT);
        } catch (Exception e) {
            log.error("删除索引异常 : {}", e.getMessage(), e);
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }

    /**
     * 创建索引
     * 当没有传参映射时，这时仅创建索引，不设置映射
     * @param indexName 索引名称
     * @param mapping 映射
     * @return 操作完成返回true,操作出现异常返回false
     */
    public Boolean createIndex(String indexName, Map<String, Object> mapping) {
        Assert.hasText(indexName, "索引名称不能为空");
        // 1 构建请求
        CreateIndexRequest request = new CreateIndexRequest(indexName);
        // 如果 mapping不为空，设置映射
        if (!CollectionUtils.isEmpty(mapping)) {
            request.mapping(mapping);
        }

        // 2 发出请求
        try {
            client.indices().create(request, RequestOptions.DEFAULT);
        } catch (Exception e) {
            log.error("创建索引异常 : {}", e.getMessage(), e);
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }

    /**
     * 创建文档
     * @param indexName 索引名称
     * @param id 文档ID
     * @param data 文档数据
     * @return 操作完成返回true,操作出现异常返回false
     */
    public Boolean createDoc(String indexName, String id, Map<String, Object> data) {
        Assert.hasText(indexName, "索引名称不能为空");
        Assert.hasText(id, "文档ID不能为空");
        Assert.notEmpty(data, "文档数据不能为空");

        // 构建请求
        IndexRequest request = new IndexRequest(indexName);
        request.id(id);
        request.source(data);

        // 发送请求
        try {
            client.index(request, RequestOptions.DEFAULT);
        } catch (Exception e) {
            log.error("创建文档异常 : {}", e.getMessage(), e);
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }

    /**
     * 修改文档
     * @param indexName 索引名称
     * @param id 文档ID
     * @param data 文档数据
     * @return 操作完成返回true,操作出现异常返回false
     */
    public Boolean updateDoc(String indexName, String id, Map<String, Object> data) {
        Assert.hasText(indexName, "索引名称不能为空");
        Assert.hasText(id, "文档ID不能为空");
        Assert.notEmpty(data, "文档数据不能为空");

        // 构建请求
        UpdateRequest request = new UpdateRequest(indexName, id);
        request.doc(data);

        // 发送请求
        try {
            client.update(request, RequestOptions.DEFAULT);
        } catch (Exception e) {
            log.error("更新文档异常 : {}", e.getMessage(), e);
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }

    /**
     * 根据文档ID删除文档
     * @param indexName 索引名称
     * @param id 文档ID
     * @return 操作完成返回true,操作出现异常返回false
     */
    public Boolean deleteDoc(String indexName, String id) {
        Assert.hasText(indexName, "索引名称不能为空");
        Assert.hasText(id, "文档ID不能为空");
        // 构建请求
        DeleteRequest request = new DeleteRequest(indexName);
        request.id(id);

        // 发出请求
        try {
            client.delete(request, RequestOptions.DEFAULT);
        } catch (Exception e) {
            log.error("删除文档异常 : {}", e.getMessage(), e);
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }
}